import os
from sqlalchemy.exc import SQLAlchemyError
from flask import request, jsonify, current_app, url_for, send_from_directory, views, render_template, redirect
from flask_ckeditor import upload_success
from . import goods_bp
from apps.goods.models import Goods
from apps.common import func
from apps.goods.forms import GoodsAddForm, GoodsEditForm
from exts import db, csrf,cache
from werkzeug.datastructures import CombinedMultiDict


class GoodsView(views.MethodView):
    def get(self):
        # goods_all = Goods.query.all()
        cates = func.binddata(0, 1)
        return render_template('shop/goods/index.html', cates=cates)


goods_bp.add_url_rule('/index', view_func=GoodsView.as_view('index'))


class GoodsAddView(views.MethodView):
    def get(self):
        cates = func.binddata(0, 1)
        form_obj = GoodsAddForm()
        form_obj.category_id.choices = cates
        return render_template('shop/goods/add.html', cates=cates, form_obj=form_obj)

    def post(self):
        cates = func.binddata(0, 1)
        f = GoodsAddForm(CombinedMultiDict([request.form, request.files]))
        print(f.status.data)
        print(type(f.status.data))
        if f.validate_on_submit():
            try:
                good = Goods()
                good.name = f.name.data
                good.category_id = f.category_id.data
                good.market_price = f.market_price.data
                good.price = f.price.data
                file = f.main_img.data
                if file:
                    good.main_img = file.filename
                good.goods_desc = f.goods_desc.data
                good.unit = f.unit.data
                good.click_num = 0
                good.status = f.status.data
                db.session.add(good)
                db.session.commit()
            except SQLAlchemyError as e:
                print(e)
                db.session.rollback()
            return redirect(url_for('goods.index'))
        else:
            errors = f.errors
            return render_template('shop/goods/add.html', form_obj=f, info=errors, cates=cates)


goods_bp.add_url_rule('/add', view_func=GoodsAddView.as_view('add'))


class GoodsEditView(views.MethodView):
    def get(self):
        form_obj = GoodsEditForm()
        id = request.args.get('id')
        good = Goods.query.get(int(id))
        form_obj.name.data = good.name
        form_obj.category_id.data = good.category_id
        form_obj.market_price.data = good.market_price
        form_obj.price.data = good.price
        form_obj.main_img.data = good.main_img
        form_obj.goods_desc.data = good.goods_desc
        form_obj.status.data = good.status
        cates = func.binddata(0, 1)
        form_obj.category_id.choices = cates
        return render_template('shop/goods/edit.html', cates=cates, form_obj=form_obj)

    def post(self):
        cates = func.binddata(0, 1)
        f = GoodsEditForm(CombinedMultiDict([request.form, request.files]))
        if f.validate_on_submit():
            try:
                good_id = request.values.get('id')
                good = Goods.query.filter_by(id=good_id).first()
                good.name = f.name.data
                good.category_id = f.category_id.data
                good.market_price = f.market_price.data
                good.price = f.price.data
                file = f.main_img.data
                if file:
                    good.main_img = file.filename
                good.goods_desc = f.goods_desc.data
                good.unit = f.unit.data
                good.click_num = 0
                good.status = f.status.data
                db.session.add(good)
                db.session.commit()
                return redirect(url_for('goods.index'))
            except SQLAlchemyError as e:
                print(e)
                db.session.rollback()
                return render_template(url_for('shop/goods/edit.html', form_obj=f, cates=cates))
        else:
            errors = f.errors
            return render_template('shop/goods/edit.html', form_obj=f, info=errors, cates=cates)


goods_bp.add_url_rule('/edit', view_func=GoodsEditView.as_view('edit'))


class GoodsDelView(views.MethodView):
    def post(self):
        id = request.values.get('good_id')
        good = Goods.query.get(int(id))
        db.session.delete(good)
        db.session.commit()
        data = {'code': 200, 'msg': '删除成功'}
        return jsonify(data)

goods_bp.add_url_rule('/delete', view_func=GoodsDelView.as_view('delete'))

@goods_bp.route('/ajax_goods')
@cache.cached(timeout=60)
def ajax_goods():
    category_id = request.args.get('cate_id', '')
    name = request.args.get('goodname', '')
    status = request.args.get('status', '')
    search_dict = dict()
    if category_id:
        search_dict['category_id'] = int(category_id)
    if name:
        search_dict['name'] = name
    if status:
        search_dict['status'] = status
    pagesize = 10
    page = int(request.args.get('page'))
    # 获取总条数
    total = Goods.query.filter_by(**search_dict).count()
    # 通过切片获取当前页和下一页的数据
    goods = Goods.query.filter_by(**search_dict).order_by(-Goods.id)[(page - 1) * pagesize:page * pagesize]
    rows = []
    datas = {'total': total, 'rows': rows}
    for good in goods:
        rows.append({'id': good.id, 'name': good.name, 'market_price': good.market_price, 'price': good.price,
                     'category_name': good.back_cate.name, 'click_num': good.click_num, 'amount': good.amount})
    return jsonify(datas)


@goods_bp.route('uploads', methods=['GET', 'POST'])
@csrf.exempt
def upload():
    f = request.files.get('upload')
    ext = f.filename.split('.')[-1].lower()
    if ext not in ['jpg', 'png', 'jpeg']:
        return '上传的图片格式不符合要求'
    app = current_app._get_current_object()
    path = os.path.join(app.config['UPLOADED_PATH'], f.filename)
    f.save(path)
    url = url_for('goods.uploaded_files', filename=f.filename)
    return upload_success(url)


@goods_bp.route('files/<filename>', methods=['GET', 'POST'])
@csrf.exempt
def uploaded_files(filename):
    app = current_app._get_current_object()
    path = app.config['UPLOADED_PATH']
    return send_from_directory(path, filename)
